from typing import Optional, Tuple, List
import uuid
import re
import json



POS_LABEL_MAP = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',';U','V','W','X','Y','Z']




def generate_uuid():
    return str(uuid.uuid4())


def parser_cell_str(cell_str):
    # return col, row
    pattern = re.compile(r'([A-Z]+)(\d+)')
    upper_cell_str = str(cell_str).upper()
    groups = re.search(pattern, upper_cell_str).groups()
    return groups[0], groups[1]
    

def parser_range_str(range_str):
    range_str = range_str.replace('：', ':').upper()
    start_cell_str, end_cell_str = range_str.split(':')
    start_col, start_row = parser_cell_str(start_cell_str)
    end_col, end_row = parser_cell_str(end_cell_str)
    return start_col, start_row, end_col, end_row

def trans_pos_label_to_coor(pos:str)->int:
    # A -> 1
    
    if pos.isalpha():
        # 表示做col坐标
        pos = pos.upper()
        len_of_pos = len(pos)
        coor = 0
        for i in range(len_of_pos):
            coor += (POS_LABEL_MAP.index(pos[len_of_pos-1-i])+1)*26**i
        return coor
    elif pos.isdigit():
        # 表示row坐标
        return int(pos)
    else:
        raise ValueError('pos is not a valid pos label')
    

def trans_coor_to_pos_label(coor:int, type="col"):
    if type == "col":
        pos = []
        while coor//26 != 0:
            pos.append(POS_LABEL_MAP[coor//26-1])
            coor %= 26
        if coor %26 != 0:
            pos.append(POS_LABEL_MAP[coor%26-1])
        return "".join(pos)
    elif type == "row":
        return str(coor)
    else:
        raise ValueError('type is not a valid type')

def check_cell_in_range(cell_pos, range_pos):
    # 判断 B1 是否在 A1:C1 中
    # range 必须是矩形
    if len(range_pos) == 0:
        return False
    cell_col, cell_row = parser_cell_str(cell_pos)
    start_col, start_row, end_col, end_row = parser_range_str(range_pos)
    cell_col_id = trans_pos_label_to_coor(cell_col)
    cell_row_id = trans_pos_label_to_coor(cell_row)
    
    range_start_col_id = trans_pos_label_to_coor(start_col)
    range_start_row_id = trans_pos_label_to_coor(start_row)
    range_end_col_id = trans_pos_label_to_coor(end_col)
    range_end_row_id = trans_pos_label_to_coor(end_row)
    
    if range_start_col_id<=cell_col_id<=range_end_col_id and range_start_row_id<=cell_row_id<=range_end_row_id:
        return True
    else:
        return False

def combination_relationships(relationships:List):
    if len(relationships) == 0:
        return relationships
    new_relationships = []
    for item_a in relationships:
        for item_b in relationships:
            new_relationships.append(f"{item_a}-{item_b}")
    relationships.extend(new_relationships)
    return list(set(relationships))

def dict_2_json(a_dict, save_path):
    with open(save_path, 'w', encoding="utf-8") as f:
        json.dump(a_dict, f, ensure_ascii=False, check_circular=True, indent=4)

if __name__ == "__main__":
    start_col, start_row, end_col, end_row = parser_range_str("AB111:IH9")
    print(start_col, start_row, end_col, end_row)
    coor = trans_pos_label_to_coor("123")
    print(coor)
    coor = trans_pos_label_to_coor("ZZ")
    print(coor)
    pos = trans_coor_to_pos_label(1, type="col")
    print(pos)
    
    cell_pos = "B2"
    range_pos = "B3:B2"
    print(check_cell_in_range(cell_pos, range_pos))
    old_re = ["A", "B", "C"]
    new_re = combination_relationships(old_re)
    print(new_re)